<?php
namespace app\beautiful\logic;
use app\beautiful\logic\LogsLogic;
use app\beautiful\model\member\MemberBalanceModel;
use app\beautiful\model\member\MemberIntegralModel;
use app\beautiful\model\setting\SettingIntegralModel;
use app\beautiful\model\setting\SettingBalanceModel;
use app\beautiful\logic\MemberLevelLogic;
class MemberWalletLogic{
    private $shopId;
    private $memberId;
    private $error;//保存最后一个ERROR信息
    private $isLevel; //是否监听等级变化
    private $balance = 0; //余额增加的数量
    private $integral = 0;//积分增加的数量
    public function __construct($shopId,$memberId) {
        $this->shopId = $shopId;
        $this->memberId = $memberId;
    }
    
    public function __destruct() { //析构函授完成等级的监控
        if($this->isLevel == true){
            MemberLevelLogic::level($this->shopId, $this->memberId, $this->balance, $this->integral);
        }
    }
    public  function getError(){
        return $this->error;
    }
    

    
    public function checkBalance($balance){
        $myBalance = MemberBalanceModel::where([
                ['shop_id','=',$this->shopId],
                ['member_id','=', $this->memberId],
                ['valid_bg_time','<=',time()],
                ['remain_balance','>',0]
            ])->sum('remain_balance');
        return $myBalance >= $balance;
    }
    
    /**
     * 检查用户的积分
     */
    public function checkIntegral($integral){
        $myIntegral = MemberIntegralModel::where([
            ['shop_id','=',$this->shopId],
            ['member_id','=', $this->memberId],
            ['expire_time','>=',time()]
        ])->sum('remain_integral');
        return $myIntegral >= $integral; 
    }
    
    public function addBalance($balance,$give_balance,$type_id,$remarks= '',$operate_id = 0){
        if($balance <= 0){
            return $this->error('充值金额不正确');
        }  
        $member_balance = new MemberBalanceModel();
        $member_balance_data[]=[
            'shop_id'=>$this->shopId,
            'member_id'=> $this->memberId,
            'balance'=>$balance,
            'remain_balance'=>$balance,
            'valid_bg_time'=>time(),
        ];
        if($give_balance >0){
            $balance_setting=SettingBalanceModel::where([['shop_id','=',$this->shopId]])->find();
            $frozen_days=$balance_setting->is_frozen_give_money ==1 ? $balance_setting->frozen_days : 0;
            $member_balance_data[]=[
                'shop_id'=>$this->shopId,
                'member_id'=> $this->memberId,
                'balance'=>$give_balance,
                'remain_balance'=>$give_balance,
                'valid_bg_time'=>time() + $frozen_days *86400,
            ];
        }
        $member_balance->saveAll($member_balance_data);
        if(!LogsLogic::balance($this->shopId, $this->memberId,1,$type_id,0,$balance,$give_balance,$remarks,$operate_id)){
            return $this->error('充值日志写入失败');
        }
        //充值的时候记录推广员业绩
        $PartnerLogic = new PartnerLogic($this->shopId);
        $PartnerLogic->commission($this->memberId,$balance);
        //充值赠送积分
        $integral_setting=SettingIntegralModel::where([['shop_id','=',$this->shopId]])->find();
        $integral= (int)(($integral_setting->recharge_give_integral_rate/100) * 10000) * ($balance * 100) /1000000;
        if($integral){
           $this->addIntegal($integral, 3);
        }else{ //如果增加积分 那么 启动就交给积分
            $this->isLevel = true;
        }
        //启动等级监控
        $this->balance = $balance;
        return  true;
    }

    public function rebackBalance($balance,$give_balance,$type_id,$remarks= '',$operate_id = 0)
    {
        if($balance <= 0){
            return $this->error('充值金额不正确');
        }
        $member_balance = new MemberBalanceModel();
        $member_balance_data[]=[
            'shop_id'=>$this->shopId,
            'member_id'=> $this->memberId,
            'balance'=>$balance,
            'remain_balance'=>$balance,
            'valid_bg_time'=>time(),
        ];
        if($give_balance >0){
            $balance_setting=SettingBalanceModel::where([['shop_id','=',$this->shopId]])->find();
            $frozen_days=$balance_setting->is_frozen_give_money ==1 ? $balance_setting->frozen_days : 0;
            $member_balance_data[]=[
                'shop_id'=>$this->shopId,
                'member_id'=> $this->memberId,
                'balance'=>$give_balance,
                'remain_balance'=>$give_balance,
                'valid_bg_time'=>time() + $frozen_days *86400,
            ];
        }
        $member_balance->saveAll($member_balance_data);
        if(!LogsLogic::balance($this->shopId, $this->memberId,1,$type_id,0,$balance,$give_balance,$remarks,$operate_id)){
            return $this->error('充值日志写入失败');
        }
        $this->balance = $balance;
        return true;
    }
    
    //支付返积分在线消费
    public function addIntegralByPayment($balance){
        $integral_setting=SettingIntegralModel::where([['shop_id','=',$this->shopId]])->find();
        $integral= (int)(($integral_setting->recharge_give_integral_rate/100) * 10000) * ($balance * 100) /1000000;
        if($integral){ //支付返积分
           $this->addIntegal($integral, 8);
        }
        return true;
    }
    
    public function addIntegal($integral,$type_id,$remarks= '',$operate_id = 0){
        if(empty($integral)){
            return $this->error('要增加的积分不能为空');
        }
        $integral_setting = SettingIntegralModel::where([['shop_id','=',$this->shopId]])->find();
        $valid_year = $integral_setting->is_expire== 0 ?  10 : $integral_setting->valid_year;
        $time = time() + $valid_year * 365 * 86400;
        $member_integral= new MemberIntegralModel();
        $member_integral->shop_id = $this->shopId;
        $member_integral->member_id= $this->memberId;
        $member_integral->integral=$integral;
        $member_integral->remain_integral=$integral;
        $member_integral->expire_time= $time;
        $member_integral->save();
        if(!LogsLogic::integral($this->shopId, $this->memberId,1,$type_id,$integral,$remarks,$operate_id)){
            return $this->error('积分日志写入失败');
        }
        //启动等级监控
        $this->integral = $this->integral ? $integral : $this->integral + $integral;
        $this->isLevel = true;
        return true;
    }
    /**
     * 使用余额外层需要用事务 错误通过 getError 获取
     * @return bool 
     */
    public function useBalance($balance,$original,$type_id,$remarks= '',$operate_id = 0){
        if($this->checkBalance($balance) == false){
            return $this->error('账户余额不足');
        }
        $needBalance = $balance;
        while (true){
            $balanceModel =  MemberBalanceModel::where([
                ['shop_id','=',$this->shopId],
                ['member_id','=', $this->memberId],
                ['valid_bg_time','<=',time()],
                ['remain_balance','>',0]
            ])->find();
            if($balanceModel === null){
                return $this->error('用户账户余额不足');
            }
            if($balanceModel->remain_balance <= $needBalance){
                $needBalance = round(($needBalance*100  - $balanceModel->remain_balance *  100)/100,2);
                $balanceModel->remain_balance = 0;
            }else{
                $balanceModel->remain_balance = round(($balanceModel->remain_balance *  100 - $needBalance*100)/100,2);
                $needBalance = 0;
            }
            $balanceModel->save();
            if($needBalance <= 0) {
                break;
            }
        }
        if(!LogsLogic::balance($this->shopId, $this->memberId,-1,$type_id,$original,$balance,0,$remarks,$operate_id)){
            return $this->error('写入余额日志错误');
        }
        return  true;
    }
    
    public function useIntegral($integral,$type_id,$remarks= '',$operate_id = 0){
        if($this->checkIntegral($integral) == false){
            return $this->error('用户账户积分不足');
        }
        $needIntegral = $integral;
        while (true){
            $integralModel =  MemberIntegralModel::where([
            ['shop_id','=',$this->shopId],
            ['member_id','=', $this->memberId],
            ['expire_time','>=',time()],
            ['remain_integral','>',0]
        ])->order(['expire_time'=>'asc'])->find();
            if(null === $integralModel){
                return $this->error('用户积分不够扣除的');
            }
            if($integralModel->remain_integral < $needIntegral){
                $needIntegral = $needIntegral - $integralModel->remain_integral;
                $integralModel->remain_integral = 0;
            }else{
                $integralModel->remain_integral = $integralModel->remain_integral - $needIntegral;
                $needIntegral = 0;
            }
            $integralModel->save();
            if($needIntegral <= 0) break;
        }
        if(!LogsLogic::integral($this->shopId, $this->memberId,-1,$type_id,$integral,$remarks,$operate_id)){
            return $this->error('积分日志写入失败');
        }
        return true;
    }
    
    public function error($message){
        $this->error = $message;
        return false;
    }
}